﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Galoap
{
    partial class GameSession
    {
        /// <summary>
        /// Returns all GameSessions
        /// </summary>
        /// <returns></returns>
        public static List<GameSession> GetAllGameSessions()
        {
            return (from GameSession in GaloapDatabase.Database.GameSession
                    select GameSession).ToList();
        }

        /// <summary>
        /// Returns the last GameSession
        /// </summary>
        /// <returns></returns>
        public static GameSession GetLastGameSession()
        {
            return (from GameSession in GaloapDatabase.Database.GameSession
                    orderby GameSession.Date descending
                    select GameSession).First();
        }

        /// <summary>
        /// Given an user this method returns the last GameSession
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public static GameSession GetLastGameSession(User user)
        {
            return (from GameSession in GaloapDatabase.Database.GameSession.Include("User")
                    where GameSession.User.UserID == user.UserID
                    orderby GameSession.Date descending
                    select GameSession).First();
        }

        /// <summary>
        /// Given a game this method returns the last GameSession
        /// </summary>
        /// <param name="game"></param>
        /// <returns></returns>
        public static GameSession GetLastGameSession(Game game)
        {
            return (from GameSession in GaloapDatabase.Database.GameSession.Include("Game")
                    where GameSession.Game.GameID == game.GameID
                    orderby GameSession.Date descending
                    select GameSession).First();
        }

        /// <summary>
        /// Given an user and a game this method returns the last GameSession
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public static GameSession GetLastGameSession(User user, Game game)
        {
            return (from GameSession in GaloapDatabase.Database.GameSession.Include("User").Include("Game")
                    where GameSession.User.UserID == user.UserID && GameSession.Game.GameID == game.GameID
                    orderby GameSession.Date descending
                    select GameSession).First();
        }


        /// <summary>
        /// Returns the GameSession with highest score for a certain date
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public static GameSession GetGameSessionWithHighestScore(DateTime date)
        {
            return (from GameSession in GaloapDatabase.Database.GameSession
                    where GameSession.Date.Day == date.Day && GameSession.Date.Month == date.Month && GameSession.Date.Year == date.Year
                    orderby GameSession.Score descending
                    select GameSession).First();
        }

        /// <summary>
        /// Give a date this method returns the GameSession with the lowest score
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public static GameSession GetGameSessionWithLowestScore(DateTime date)
        {
            return (from GameSession in GaloapDatabase.Database.GameSession
                    where GameSession.Date.Date == date.Date
                    orderby GameSession.Score ascending
                    select GameSession).First();
        }

        /// <summary>
        /// Given an user this method returns the GameSession with the highest score
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public static List<GameSession> GetUserGameSessionsWithHighestScore(User user)
        {
            return (from GameSession in GaloapDatabase.Database.GameSession.Include("User")
                    where GameSession.User.UserID == user.UserID
                    group GameSession by GameSession.Score into scoreGroup
                    orderby scoreGroup.Key descending
                    select scoreGroup).First().ToList();
        }

        /// <summary>
        /// Given an user this method returns the GameSession with the lowest score
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public static List<GameSession> GetUserGameSessionsWithLowestScore(User user)
        {
            return (from GameSession in GaloapDatabase.Database.GameSession.Include("User")
                    where GameSession.User.UserID == user.UserID
                    group GameSession by GameSession.Score into scoreGroup
                    orderby scoreGroup.Key ascending
                    select scoreGroup).First().ToList();
        }

        /// <summary>
        /// Returns the date that has the most GameSessions
        /// </summary>
        /// <returns></returns>
        public static DateTime GetDayWithMaxGameSessions()
        {
            return (from GameSession in GaloapDatabase.Database.GameSession
                    group GameSession by new { GameSession.Date.Year, GameSession.Date.Month, GameSession.Date.Day } into dateGroup
                    orderby dateGroup.Count() descending
                    select dateGroup).First().First().Date;
        }

        /// <summary>
        /// Returns a list of game sessions for a certain day
        /// </summary>
        /// <returns></returns>
        public static List<GameSession> GetGameSessionsByDate(DateTime date)
        {
            return (from GameSession in GaloapDatabase.Database.GameSession
                    where GameSession.Date.Year == date.Year && GameSession.Date.Month == date.Month && GameSession.Date.Day == date.Day
                    select GameSession).ToList();
        }


        /// <summary>
        /// List of questions asked in this GameSession
        /// </summary>
        /// <returns></returns>
        public List<Question> GetQuestions()
        {
            Answer.Load();
            foreach (Answer answer in Answer) answer.QuestionReference.Load();
            return (from answer in Answer
                    let question = answer.Question
                    select question).ToList();
        }

        public void Add(Answer answer)
        {
            this.Answer.Load();
            this.Answer.Add(answer);
        }

        /// <summary>
        /// Adds this to the database
        /// </summary>
        public void AddGameSessionToDB()
        {
            this.Date = DateTime.Now;
            GaloapDatabase.Database.AddToGameSession(this);

            Game.UserGame.Load();
            foreach (UserGame usergame in Game.UserGame) usergame.UserReference.Load();

            if ((from userGame in Game.UserGame
                 where userGame.User.UserID == User.UserID
                 select userGame).Count() == 0)
            {
                UserGame ug = new UserGame();
                ug.User = User;
                ug.Game = Game;
                GaloapDatabase.Database.AddToUserGame(ug);
            }

            GaloapDatabase.Database.SaveChanges();
        }

        /// <summary>
        /// Saves the current state of this in the database
        /// </summary>
        public void Save()
        {
            GaloapDatabase.Database.SaveChanges();
        }
        /// <summary>
        /// Peppe
        /// </summary>
        /// <param name="gs"></param>
        public static void TerminateSession(GameSession gs)
        {
            gs.Terminated = true;
            GaloapDatabase.Database.SaveChanges();
        }

        /// <summary>
        /// Peppe
        /// </summary>
        /// <param name="player"></param>
        /// <param name="game"></param>
        /// <returns></returns>
        public static GameSession CreateGameSession(User player, Game game)
        {
            GameSession gs = new ImageTagGameSession { Game = game, User = player, Score = 0, Level = 1, Terminated = false, Date = DateTime.Now };
            GaloapDatabase.Database.AddToGameSession(gs);
            GaloapDatabase.Database.SaveChanges();
         
            return gs;

        }
    }
}